﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Data;

namespace nwrole.toolbox.sync.extensions
{
    public static class DataTableExtension
    {
        public static void LightWeightSerialize(this DataTable myDataTable, out byte[] serializedTableData, out string tableSchema)
        {
            //Get all row values as jagged object array
            object[][] tableItems = new object[myDataTable.Rows.Count][];
            for (int rowIndex = 0; rowIndex < myDataTable.Rows.Count; rowIndex++)
                tableItems[rowIndex] = myDataTable.Rows[rowIndex].ItemArray;

            //binary serialize jagged object array
            BinaryFormatter serializationFormatter = new BinaryFormatter();
            MemoryStream buffer = new MemoryStream();
            serializationFormatter.Serialize(buffer, tableItems);
            serializedTableData = buffer.ToArray();

            //Get table schema
            StringBuilder tableSchemaBuilder = new StringBuilder();
            myDataTable.WriteXmlSchema(new StringWriter(tableSchemaBuilder));
            tableSchema = tableSchemaBuilder.ToString();
        }

        public static DataTable LightWeightDeserialize(this byte[] serializedTableData, string tableSchema)
        {
            DataTable table = new DataTable();
            table.ReadXmlSchema(new StringReader(tableSchema));

            BinaryFormatter serializationFormatter = new BinaryFormatter();
            MemoryStream buffer = new MemoryStream(serializedTableData);
            object[][] itemArrayForRows = (object[][])serializationFormatter.Deserialize(buffer);

            table.MinimumCapacity = itemArrayForRows.Length;
            table.BeginLoadData();
            for (int rowIndex = 0; rowIndex < itemArrayForRows.Length; rowIndex++)
                table.Rows.Add(itemArrayForRows[rowIndex]);
            table.EndLoadData();

            return table;
        }
    }
}
